<?php

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 * Description of BUIScreenFlow
 *
 * @author jianfeng
 */
class BUIScreenFlow_old extends BUIControl implements Iterator {

    const NEXT = "next";
    const FIRST = "first";
    const PREVIOUS = "previous";
    const LAST = 'last';
    const ContextVARIABLE_SCREENFLOW_INDEX = 'screenFlowIndex';

    protected $flow = null;
    protected $screenFlowLayout = "screenflowLayout";
    protected $index = 0;
    public $screens = array();
    protected $nextIndex = null;
    protected $previousIndex = null;
    public $firstIndex = 0;
    public $lastIndex = null;
    protected $name = null;
    protected $flowName = null;
    protected $menus = null;
    protected $currentScreen = null;
    protected $uiNode = null;
    public $ContextScopeName = 'ScreenFlow';
    private $isMenuRendered = false;
    private $isContentRendered = false;
    public $views = null;
    public $layoutView = null;
    protected $node = null;

    public function __construct($name = null, $parent = NULL) {

        if ($name != NULL) {
            $this->flowName = $name;

            parent::__construct();

            //set default screenflow path
            $currentNode = Blyn::app()->getCurrentNode();

            if ($currentNode instanceof BOperation)
                $path = Blyn::app()->getActiveApp()->getUIManager()->screenflowPath;
            else {
                $path = $currentNode->getUIManager()->screenflowPath;
            }
            $path = Yii::getPathOfAlias($path) . '/' . $name . ".php";

            $this->flow = require($path);
            $this->parseScreenFlow($this->flow);
        }

        //$scopeId = 'ScreenFlow_' . str_replace(" ", "_", $this->getName());
        //$this->resetContextVariables($scopeId, $this->ContextScopeName);
    }

    public function setUINode($uiNode = NULL) {

        if ($uiNode == NULL) {
            $uiNode = Blyn::app()->getCurrentNode()->getUIManager();
            $node = Blyn::app()->getCurrentNode();
        } else {
            if ($uiNode instanceof BUINode)
                $node = $uiNode->getNode();
        }

        $this->uiNode = $uiNode;
        $this->node = $node;
    }

    public function setNode($node = NULL) {
        //if ($node == NULL)
        //    $node = Blyn::app()->getCurrentNode();
        $this->node = $node;
    }

    public function getUINode() {
        if ($this->uiNode == NULL)
            $this->uiNode = Blyn::app()->getCurrentNode()->getUIManager();
        return $this->uiNode;
    }

    public function getNode() {
        //if ($this->node == NULL)
        //    $this->node = Blyn::app()->getCurrentNode();
        return $this->node;
    }

    protected function parseScreenFlow($flow) {
        $this->screens = $flow['screens'];
        $this->lastIndex = count($this->screens) - 1;
        $this->name = $flow['name'];

        $this->layoutView = isset($flow['layoutView']) ? $flow['layoutView'] : NULL;
        $this->views = isset($flow['views']) ? $flow['views'] : NULL;
        //$this->menus = $flow['menus'];
    }

    public function renderMenu($data = null, $style = null) {

        if ($_POST != NULL)
            $this->isMenuRendered = !$this->isMenuRendered;

        if (!$this->isMenuRendered) {
            foreach ($this->menus as $menuname => $menu) {
                if (isset($menu['visible']) && $menu['visible']) {
                    $this->showMenu($menuname, $menu, $data, $style);
                }
            }
        }
    }

    protected function showMenu($menuName, $menu = null, $data = null) {

        if (!is_array($data))
            $data = array();

        $percent = round(($this->index + 1) / ($this->lastIndex + 1) * 100);
        $data['percent'] = $percent;

        $viewName = 'screenflow_' . $menuName;
        $viewName = strtolower($viewName);
        $controller = yii::app()->getController();
        $controller->renderPartial($viewName, $data);
    }

    public function renderContent($data) {

        if (!$this->isContentRendered) {

            if (!is_array($data))
                $data = array();

            $this->currentScreen->onRender($data);
        }
    }

    public function onRender($data = null) {

        $flowIndex = $this->getContextVariable(BUIScreenFlow::ContextVARIABLE_SCREENFLOW_INDEX);
        if (is_numeric($flowIndex) && $flowIndex > 0)
            $this->setIndex($flowIndex);

        $uiNode = Blyn::app()->getCurrentNode()->getUIManager();
        $uiNode->setCurrentScreenFlow($this);

        //$this->addRenderView('screeflowLayout', $this->getLayoutView(), array('uiObj' => $this));
        //   $this->gotoScreenByIndex($this->index);
        //add controls

        if (Blyn::app()->getUIManager()->getCurrentScreen() != NULL) {
            $uiScreen = Blyn::app()->getUIManager()->getCurrentScreen();
        } else {
            $uiScreen = new BUIScreen();
        }
        $this->addControl($uiScreen);
    }

    public function getScreenFlowLayout() {
        $viewPath = Blyn::app()->getCurrentNode()->getUIManager()->viewPath;
        $screenFlowLayout = $viewPath . '.' . $this->screenFlowLayout;

        if (!file_exists($screenFlowLayout))
            $screenFlowLayout = Blyn::app()->getAppUI()->viewPath . '.' . 'screenflowLayout';

        return $screenFlowLayout;
    }

    public function gotoScreenByIndex($index = 0, $data = array()) {

        //     $flowData = array();

        if ($index < 0 || $index > $this->lastIndex)
            return false;

        $this->index = $index;
        $this->currentScreen = $this->getScreenByIndex($this->index);

        //$this->addRenderView('screenLayout', $this->currentScreen->getLayoutView(), array('uiObj' => $this->currentScreen));
        //$this->currentScreen->render($data);
        parent::gotoScreen($this->currentScreen);
    }

    public function getTitle() {
        
    }

    public function getName() {
        if ($this->name == NULL)
            $this->name = parent::getName();
        return $this->name;
    }

    public function getScreenFlowName() {
        return $this->flowName;
    }

    public function setIndex($index) {
        $this->index = $index;
    }

    public function getIndex() {
        return $this->index;
    }

    public function getScreenByIndex($index) {
        $screen = null;

        if (isset($this->screens[$index])) {
            $screenConfig = $this->screens[$index];
            if (isset($screenConfig['class']))
                $screenClass = $screenConfig['class'];
            else
                $screenClass = 'BScreen' . $screenConfig['name'];

            $screen = new $screenClass();
            $screen->setParent($this);

//            $currentUINode = Blyn::app()->getCurrentNode()->getUIManager();
//            $currentUINode->currentScreen = $screen;

            return $screen;
        }

        return FALSE;
    }

    public function getCurrentScreen() {
        if ($this->currentScreen != NULL) {
            $currentIndexScreen = $this->getScreenByIndex($this->index);
            if (get_class($this->currentScreen) == get_class($currentIndexScreen) && $this->currentScreen->getName() == $currentIndexScreen->getName())
                return $this->currentScreen;
        }
        $this->currentScreen = $this->getScreenByIndex($this->index);
        return $this->currentScreen;
    }

    public function gotoScreen($name, $data = NULL) {
        if ($name == self::NEXT) {
            $this->next();
            $this->gotoScreenByIndex($this->index, $data);
            return;
        }

        if ($name == self::PREVIOUS) {
            $this->previous();
            $this->gotoScreenByIndex($this->index, $data);
            return;
        }

        if ($name == self::FIRST) {
            $this->index = 0;
            $this->gotoScreenByIndex($this->index, $data);
            return;
        }

        if ($name == self::LAST) {
            $this->index = $this->lastIndex;
            $this->gotoScreenByIndex($this->index, $data);
            return;
        }

        $this->index = $this->getIndexByName($name);
        return $this->gotoScreenByIndex($this->index);
    }

    public function getIndexByName($name) {
        $i = 0;
        foreach ($this->screens as $screen) {
            $screenClass = isset($screen['class']) ? $screen['class'] : 'no-class';
            $screenName = 'BScreen' . $screen['name'];
            if ($name == $screenName || $name == $screenClass || $name == $screen['name'])
                return $i;
            $i++;
        }
        return -1;
    }

    public function getScreenByName($name) {
        if ($name == self::NEXT) {
            $this->index++;
            return $this->current();
        }

        if ($name == self::PREVIOUS) {
            $this->index--;
            return $this->current();
        }

        if ($name == self::FIRST) {
            $this->index = 0;
            return $this->current();
        }

        if ($name == self::LAST) {
            $this->index = $this->lastIndex;
            return $this->current();
        }

        $this->index = $this->getIndexByName($name);

        if ($this->index < 0 || $this->index > $this->lastIndex)
            return false;
        else
            return $this->current();
    }

    public function current() {
        $screen = $this->getScreenByIndex($this->index);
        if ($screen instanceof BUIScreen)
            $screen->setParent($this);
        return $screen;
    }

    public function key() {
        return $this->index;
    }

    public function next() {
        ++$this->index;
    }

    public function previous() {
        --$this->index;
    }

    public function rewind() {
        $this->index = 0;
    }

    public function valid() {
        return isset($this->screens[$this->index]);
    }

    public function addContextVariable($name, $value, $scope = NULL, $type = NULL) {

        $tObj = Blyn::app()->getContextObj();

        $tObj->addContextVariable(BContextObj::Scope_ScreenFlow, $name, $value);
    }

    public function getContextVariable($name, $scope = NULL, $type = NULL) {

        $tObj = Blyn::app()->getContextObj();

        /*
          if ($name == BContextObj::VariableName_Id)
          return $tObj->getContextVariable(BContextObj::Scope_AppMeta, BContextObj::V_CurrentScreenFlowId);
          if ($name == BContextObj::VariableName_Class)
          return $tObj->getContextVariable(BContextObj::Scope_AppMeta, BContextObj::V_CurrentScreenFlowClass);
         * 
         */

        return $tObj->getContextVariable(BContextObj::Scope_ScreenFlow, $name);
    }

    public function resetContextVariable($name = NULL) {

        $tObj = Blyn::app()->getContextObj();
        /**
         * for scope reset, only happen when id changed
         */
        if ($name == NULL) {
            $tId = $this->getContextVariable(BContextObj::Current_Id);
            $myId = $this->getId();
            if ($tId != $myId) {
                $tObj->resetContextVariable(BContextObj::Scope_ScreenFlow);
                //$tObj->resetContextVariable(BContextObj::Scope_AppMeta, BContextObj::V_CurrentScreenFlowId);
                //$tObj->resetContextVariable(BContextObj::Scope_AppMeta, BContextObj::V_CurrentScreenFlowClass);
                $this->addContextVariable(BContextObj::Current_Id, $myId);
            }
        } else {
            //reset name can alway do   
            /*
              if (name == BContextObj::VariableName_Id)
              return $tObj->resetContextVariable(BContextObj::Scope_AppMeta, BContextObj::V_CurrentScreenFlowId);
              if (name == BContextObj::VariableName_Class)
              return $tObj->resetContextVariable(BContextObj::Scope_AppMeta, BContextObj::V_CurrentScreenFlowClass);
             * 
             */
            $tObj->resetContextVariable(BContextObj::Scope_ScreenFlow, $name);
        }
    }

    protected function registerMenu($event) {
        
    }

    public function getUrl($data = NULL) {
        if ($data == NULL)
            $data = array();

        $data['blyn_sf'] = $this->getScreenFlowName();
        $url = $this->getUINode()->getUrl($data);

        if (isset($data['ajaxLink'])) {
            $index = $this->getIndex();
            if (isset($data['screenFlowIndex']))
                $index = $data['screenFlowIndex'];
            $ajaxLink = $data['ajaxLink'];
            //must unset ajaxLink here, otherwise maybe cause some error
            unset($data['ajaxLink']);
            $ajaxLinkId = isset($ajaxLink['id']) ? $ajaxLink['id'] : $this->flowName . $index;
            $ajaxLinkName = isset($ajaxLink['name']) ? $ajaxLink['name'] : $this->screens[$index]['name'];

            $url = $this->getUINode()->getUrl($data);

            return $this->buildLink($ajaxLinkId, $ajaxLinkName, BUIBase::LinkType_AjaxLink, $url);
        }

        //$data['blyn_sf'] = $this->getScreenFlowName();

        return $url;
    }

    public function getAjaxLink($name, $data = NULL, $sender = NULL, $router = 'site/index', $updateControl = NULL) {
        if ($this->getNode() != NULL && Blyn::app()->getCurrentNode()->getId() != $this->getNode()->getId())
            return $this->getNode()->getAjaxLink($name, $data, $sender, $router, $updateControl);
        else
            return parent::getAjaxLink($name, $data, $sender, $router, $updateControl);
        //return parent::createAjaxLink($name, $this->getUrl(), BUIBase::ajaxContainter_Space, Blyn::app()->getActiveSpace()->getUIManager()->getLayoutView(), $data);
    }

    public function getViews() {

        if ($this->views == NULL)
            $this->views = array();

        //$this->views['screenFlowTopBar'] = array('defaultScreenFlowTopBar');

        return $this->views;
    }

    /*
      public function getLayoutView() {
      if ($this->layoutView == NULL)
      $this->layoutView = 'defaultScreenFlowLayout';

      return $this->layoutView;
      }
     * 
     */

    public function getId() {
        $id = NULL;
        if ($this->getNode() != NULL) {
            $id = get_class($this->getNode()) . '_' . $this->getNode()->getId() . "_" . $this->flowName;
        }
        return $id;
    }

    public function getAjaxContainerId($data = null) {
        //parent::getAjaxContainerId($data);
        return BUIBase::ajaxContainter_screenFlow;
    }

}

?>
